home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / C de cerca / Codewarrior Lite / MacOS Support / Headers / ANSI Headers / bits < prev    next >
Text File  |  1995-12-29  |  5KB  |  213 lines

  1. // bits standard header
  2. #ifndef _BITS_
  3. #define _BITS_
  4. #include <string>
  5.  
  6. #if __MWERKS__
  7. #pragma options align=mac68k
  8.  
  9. #if __CFM68K__ && __USING_IMPORTED_ANSI__
  10. #pragma import on
  11. #endif
  12. #endif
  13.  
  14.         // template class bits
  15. string _Bitsxstr(istream&, size_t);
  16. template<size_t _N> class bits {
  17.     typedef unsigned long _T;
  18. public:
  19.     bits()
  20.         {_Tidy(); }
  21.     bits(unsigned long _X)
  22.         {_Tidy();
  23.         for (size_t _P = 0; _X != 0 && _P < _N; _X >>= 1, ++_P)
  24.             if (_X & 1)
  25.                 set(_P); }
  26.     bits(const string& _S, size_t _P = 0, size_t _L = NPOS)
  27.         {if (_S.length() < _P)
  28.             _Xran();
  29.         if (_S.length() - _P < _L)
  30.             _L = _S.length() - _P;
  31.         if (_N < _L)
  32.             _L = _N;
  33.         _Tidy(), _P += _L;
  34.         for (size_t _I = 0; _I < _L; ++_I)
  35.             if (_S[--_P] == '1')
  36.                 set(_I);
  37.             else if (_S[_P] != '0')
  38.                 _Xinv(); }
  39.     bits<_N>& operator&=(const bits<_N>& _R)
  40.         {for (int _I = _Nw; 0 <= _I; --_I)
  41.             _A[_I] &= _R._W(_I);
  42.         return (*this); }
  43.     bits<_N>& operator|=(const bits<_N>& _R)
  44.         {for (int _I = _Nw; 0 <= _I; --_I)
  45.             _A[_I] |= _R._W(_I);
  46.         return (*this); }
  47.     bits<_N>& operator^=(const bits<_N>& _R)
  48.         {for (int _I = _Nw; 0 <= _I; --_I)
  49.             _A[_I] ^= _R._W(_I);
  50.         return (*this); }
  51.     bits<_N>& operator<<=(size_t _P)
  52.         {if (_P < 0)
  53.             return (*this >>= -_P);
  54.         const int _D = _P / _Nb;
  55.         if (_D != 0)
  56.             for (int _I = _Nw; 0 <= _I; --_I)
  57.                 _A[_I] = _D <= _I ? _A[_I - _D] : 0;
  58.         if ((_P %= _Nb) != 0)
  59.             {for (int _I = _Nw; 0 < _I; --_I)
  60.                 _A[_I] = (_A[_I] << _P)
  61.                     | (_A[_I - 1] >> (_Nb - _P));
  62.             _A[0] <<= _P, _Trim(); }
  63.         return (*this); }
  64.     bits<_N>& operator>>=(size_t _P)
  65.         {if (_P < 0)
  66.             return (*this <<= -_P);
  67.         const int _D = _P / _Nb;
  68.         if (_D != 0)
  69.             for (int _I = 0; _I <= _Nw; ++_I)
  70.                 _A[_I] = _D <= _Nw - _I ? _A[_I + _D] : 0;
  71.         if ((_P %= _Nb) != 0)
  72.             {for (int _I = 0; _I < _Nw; ++_I)
  73.                 _A[_I] = (_A[_I] >> _P)
  74.                     | (_A[_I + 1] << (_Nb - _P));
  75.             _A[_Nw] >>= _P; }
  76.         return (*this); }
  77.     bits<_N>& set()
  78.         {_Tidy(~(_T)0);
  79.         return (*this); }
  80.     bits<_N>& set(size_t _P, _Bool _X = 1)
  81.         {if (_N <= _P)
  82.             _Xran();
  83.         if (_X)
  84.             _A[_P / _Nb] |= (_T)1 << _P % _Nb;
  85.         else
  86.             _A[_P / _Nb] &= ~((_T)1 << _P % _Nb);
  87.         return (*this); }
  88.     bits<_N>& reset()
  89.         {_Tidy();
  90.         return (*this); }
  91.     bits<_N>& reset(size_t _P)
  92.         {return (set(_P, 0)); }
  93.     bits<_N> operator~() const
  94.         {return (bits<_N>(*this).toggle()); }
  95.     bits<_N>& toggle()
  96.         {for (int _I = _Nw; 0 <= _I; --_I)
  97.             _A[_I] = ~_A[_I];
  98.         _Trim();
  99.         return (*this); }
  100.     bits<_N>& toggle(size_t _P)
  101.         {if (_N <= _P)
  102.             _Xran();
  103.         _A[_P / _Nb] ^= (_T)1 << _P % _Nb;
  104.         return (*this); }
  105.     unsigned short to_ushort() const
  106.         {unsigned long _V = to_ulong();
  107.         if (~(unsigned short)0 < _V)
  108.             _Xoflo();
  109.         return (_V); }
  110.     unsigned long to_ulong() const
  111.         {enum {_Assert = 1 /
  112.             (sizeof (unsigned long) % sizeof (_T) == 0)};
  113.         int _I = _Nw;
  114.         unsigned long _V;
  115.         for (; sizeof (unsigned long) / sizeof (_T) <= _I; --_I)
  116.             if (_A[_I] != 0)
  117.                 _Xoflo();
  118.         for (_V = _A[_I]; 0 <= --_I; )
  119.             _V = _V << _Nb | _A[_I];
  120.         return (_V); }
  121.     string to_string() const
  122.         {string _S(_N, reserve);
  123.         for (size_t _P = _N; 0 < _P; )
  124.             _S += test(--_P) ? '1' : '0';
  125.         return (_S); }
  126.     size_t count() const
  127.         {size_t _V = 0;
  128.         for (int _I = _Nw; 0 <= _I; --_I)
  129.             for (_T _X = _A[_I]; _X != 0; _X >>= 4)
  130.                 _V += "\0\1\1\2\1\2\2\3"
  131.                     "\1\2\2\3\2\3\3\4"[_X & 0xF];
  132.         return (_V); }
  133.     size_t length() const
  134.         {return (_N); }
  135.     _Bool operator==(const bits<_N>& _R) const
  136.         {for (int _I = _Nw; 0 <= _I; --_I)
  137.             if (_A[_I] != _R._W(_I))
  138.                 return (0);
  139.         return (1); }
  140.     _Bool operator!=(const bits<_N>& _R) const
  141.         {return (!(*this == _R)); }
  142.     _Bool test(size_t _P) const
  143.         {if (_N <= _P)
  144.             _Xran();
  145.         return ((_A[_P / _Nb] & ((_T)1 << _P % _Nb)) != 0); }
  146.     _Bool any() const
  147.         {for (int _I = _Nw; 0 <= _I; --_I)
  148.             if (_A[_I] != 0)
  149.                 return (1);
  150.         return (0); }
  151.     _Bool none() const
  152.         {return (!any()); }
  153.     bits<_N> operator<<(size_t _R) const
  154.         {return (bits<_N>(*this) <<= _R); }
  155.     bits<_N> operator>>(size_t _R) const
  156.         {return (bits<_N>(*this) >>= _R); }
  157.     friend bits<_N> operator&(const bits<_N>& _L,
  158.         const bits<_N>& _R)
  159.         {return (bits<_N>(_L) &= _R); }
  160.     friend bits<_N> operator|(const bits<_N>& _L,
  161.         const bits<_N>& _R)
  162.         {return (bits<_N>(_L) |= _R); }
  163.     friend bits<_N> operator^(const bits<_N>& _L,
  164.         const bits<_N>& _R)
  165.         {return (bits<_N>(_L) ^= _R); }
  166.     friend istream& operator>>(istream& _I, bits<_N>& _R)
  167.         {_R = _Bitsxstr(_I, _N);
  168.         return (_I); }
  169.     friend ostream& operator<<(ostream& _O, const bits<_N>& _R)
  170.         {return (_O << _R.to_string()); }
  171.     _T _W(size_t _I) const
  172.         {return (_A[_I]); }
  173. private:
  174.     enum {_Nb = _BITS_BYTE * sizeof (_T),
  175.         _Nw = _N == 0 ? 0 : (_N - 1) / _Nb};
  176.     void _Tidy(_T _X = 0)
  177.         {for (int _I = _Nw; 0 <= _I; --_I)
  178.             _A[_I] = _X;
  179.         if (_X != 0)
  180.             _Trim(); }
  181.     void _Trim()
  182.         {if (_N % _Nb != 0)
  183.             _A[_Nw] &= ((_T)1 << _N % _Nb) - 1; }
  184.     void _Xinv() const
  185.         {invalidargument("invalid bits<N> char").raise(); }
  186.     void _Xoflo() const
  187.         {overflow("bits<N> conversion overflow").raise(); }
  188.     void _Xran() const
  189.         {outofrange("invalid bits<N> position").raise(); }
  190.     _T _A[_Nw + 1];
  191.     };
  192.  
  193. #if __MWERKS__
  194. #if __CFM68K__ && __USING_IMPORTED_ANSI__
  195. #pragma import reset
  196. #endif
  197.  
  198. #pragma options align=reset
  199. #endif
  200.  
  201. #endif
  202.  
  203. /*
  204.  * Copyright (c) 1994 by P.J. Plauger.  ALL RIGHTS RESERVED. 
  205.  * Consult your license regarding permissions and restrictions.
  206.  */
  207.  
  208. /* Change log:
  209.  *94June04 PlumHall baseline
  210.  *94Sept30 Applied diffs for Thu Aug 25 23:22:57 1994
  211.  *94Oct07 Inserted MW changes.
  212.  */
  213.